package com.test.util;

import com.test.constants.Erc20Constants;
import com.test.contract.HT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.utils.Convert;
import org.web3j.utils.Convert.Unit;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * HT 工具类
 */
public class HTUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(HTUtil.class);
	
	/**
	 * 通过钱包文件，加载智能合约
	 * @param password
	 * @param keystoreFileName
	 * @return ht
	 */
	public static HT loadContract(String password, String keystoreFileName) {
		try {
			// 通过钱包文件加载凭证
			String keystoreFilePath = Erc20Constants.WALLET_FILE_PATH + File.separator + keystoreFileName;
			Credentials credentials = WalletUtils.loadCredentials(password, keystoreFilePath);
			HT ht = HT.load(
					Erc20Constants.CONTRACT_ADDRESS_HT, 
					Web3JClient.getWeb3j(),
					credentials, 
					ETHUtil.getGasPriceByGasApi(), // 默认为Contract.GAS_PRICE
					Erc20Constants.GAS_LIMIT_HT); // 默认为Contract.GAS_LIMIT
			return ht;
		} catch (Exception e) {
			logger.error("loadcontract_ht_exception:{}", e);
		}
		return null;
	}
	
	/**
	 * 查询余额
	 * @param ht
	 * @param address
	 * @return
	 */
	public static BigDecimal balanceOf(HT ht, String address) {
		logger.info("enter method balanceOf(). address:{}", address);
		if(ht==null) {
			return null;
		}
		
		try {
			BigInteger balanceByWei = ht.balanceOf(address).send();
			if(balanceByWei!=null) {
				// 单位转换：HT精度是18（ETHER）
				BigDecimal balance = Convert.fromWei(new BigDecimal(balanceByWei), Unit.ETHER);
				logger.info("balanceOf_{}_balance is {} ht.", address, balance);
				return balance;
			}
		} catch (Exception e) {
			logger.error("balanceOf_{}_exception:{}", address, e);
		}
		return null;
	}
	
	/**
	 * 转账
	 * @param ht
	 * @param fromAddress
	 * @param toAddress
	 * @param amount
	 * @return 交易hash
	 */
	public static String transfer(HT ht, String fromAddress, String toAddress, BigDecimal amount) {
		logger.info("enter method transfer(). fromAddress:{}, toAddress:{}, amount:{}",
				fromAddress, toAddress, amount);
		if(ht==null) {
			return null;
		}
		
		try {
			BigDecimal walue = Convert.toWei(amount, Unit.ETHER); // 转换单位
			TransactionReceipt transactionReceipt = ht.transfer(toAddress, walue.toBigInteger()).send();
			if(transactionReceipt!=null) {
				String txHash = transactionReceipt.getTransactionHash();
				logger.info("transfer_ht_fromAddress_{}_success. txHash:{}", fromAddress, txHash);
				return txHash;
			}
		} catch (Exception e) {
			logger.error("transfer_ht_fromAddress_{}_exception：{}", fromAddress, e);
			if(e.getMessage()!=null && e.getMessage().indexOf("insufficient")>0) { // eth余额不足
				return "";
			}
			if(e.getMessage()!=null && e.getMessage().indexOf("600 seconds")>0) { // 交易超时，手动处理
				return "timeout";
			}
		}
		return null;
	}

	/**
	 * main
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		// 加载合约
//		String keystoreFileName = "UTC--2020-12-10T01-35-09.800000000Z--1d37f0925958d4ff74d38a39d8ee306d0d8f07e2.json";
//		HT ht = loadContract("dHJ4QDEzNTc5", keystoreFileName);

		// 获取代币精度
//		BigInteger decimals = ht.decimals().send();
//		System.out.println("HT decimals:"+decimals);
		
		// 查询余额
//        String address = "0x1d37f0925958d4ff74d38a39d8ee306d0d8f07e2";
//        address = "0xbffb13fc5fb0c1ce1c3e6108bb262581d35baca1";
//		BigDecimal balance = balanceOf(ht, address);
//		System.out.println("HT balance of "+address+" is : "+balance.toPlainString());
		
		// 转账
//		String toAddress = "0x3391fb0dc9f1807ef1fa9680f788a97db4017255";
//		BigDecimal amount = new BigDecimal("5");
//		String txId = transfer(ht, toAddress, amount);
//		System.out.println("txId: " + txId);
//		// 再次查询余额
//		balance = balanceOf(ht, address, Unit.ETHER);
//		System.out.println("balance of "+address+" is : "+balance.toPlainString());
		
	}

}
